﻿// ChatClient.cpp : implementation file
//

#include "stdafx.h"
#include<varargs.h>
#include"protocal.h"
#include<string.h>
#include "chat_admin.h"
#include "ChatClient.h"
#include "ChatManager.h"
#include<Md5.h>
static char * key="sss";
// ChatClient
ChatClient* ChatClient::s_client=nullptr;
bool ChatClient::login=false;
ChatClient::ChatClient()
{
	CAsyncSocket::Create();
}

ChatClient* ChatClient::Instance(std::string ip,int port)
{
	if(!ChatClient::s_client)
	{
		ChatClient::s_client=new ChatClient(ip,port);
	}
	return ChatClient::s_client;
}
ChatClient::ChatClient(std::string &ip,int port)
	:m_ip(ip),m_port(port),m_policy_send_ok(FALSE)
{
	Create();
	ConnectServer();
}
BOOL ChatClient::ConnectServer()
{
	BOOL ret=false;
	CString cs(m_ip.c_str());
	ret=Connect(cs,m_port);
	return ret;
}

void ChatClient::SendPolicyRequest()
{
	const char *policy="<policy-file-request/>";
	SendToServer(policy);

}

void ChatClient::OnConnect(int errCode)
{
	CAsyncSocket::OnConnect(errCode);
	SendPolicyRequest();

}

void ChatClient::OnSend(int errCode)
{
	char buff[BUFF_LEN]={0},*p=nullptr;
	int len=0;
	//CString cs;
	//cs.Format(L"%d",errCode);
	//AfxMessageBox(cs);
	while(m_send_queue.size()>0)
	{
		p=m_send_queue.front();
		len=strlen(p);
		strncpy_s(buff,p,len);
		//Send(buff,len);
		m_send_queue.pop_front();
		delete p;
	}
	CAsyncSocket::OnSend(errCode);
	
}
UINT ChatClient::ProcessResult(LPVOID p)
{
	ChatClient* client=(ChatClient*)p;
	Json::Value root;
	Json::Reader reader;
	Json::FastWriter writer;
	if(client)
	{
		std::for_each(client->m_deque.begin(),client->m_deque.end(),[&](std::string ss){
			if(strncmp(ss.c_str(),"<cross-domain-policy>",21)==0)
			{
				login=true;
				//AfxMessageBox(L"Policy Request Ok");
				return;
			}
			if(ss.size()>0&&reader.parse(ss,root))
			{
				if(root.isMember("c"))
				{
					
					if(strncmp(root["c"].asCString(),"login",5)==0)
					{
						HWND dialog=FindWindowA(nullptr,"connection_box");
						SendMessage(dialog,WM_CLOSE,0,0);
						return;
					}
				}
				ChatManager::Instance(client)->DoResultProcess(&root);

			}
			
		});
	}
	client->m_deque.clear();
	return 0;
}
void ChatClient::OnReceive(int errCode)
{
	int len=0;
	int head_len=4;
	char head[4]={0};
    if(login==false)
	{
		len=Receive(m_buffer,BUFF_LEN);
		char * buff=new char[len+1];
		memset(buff,0,len);
		strncpy_s(buff,len+1,m_buffer,len);
		m_deque.push_back(buff);
		memset(m_buffer,0,BUFF_LEN);
	}
	while(Receive(head,head_len)==head_len&&login==true)
	{
		len|=head[0]<<24;
		len|=head[1]<<16;
		len|=head[2]<<8;
		len|=head[3];
		if(len<=0)
		{
			break;
		}
		//CString cs;
		//cs.Format(L"%d",len);
		//AfxMessageBox(cs);
		while(len>0&&len!=(Receive(m_buffer,len)));
		char * buff=new char[len+1];
		memset(buff,0,len);
		strncpy_s(buff,len+1,m_buffer,len);
		m_deque.push_back(buff);
		memset(m_buffer,0,BUFF_LEN);
	
	}
	int code=WSAGetLastError();
	CAsyncSocket::OnReceive(errCode);
	AfxBeginThread(ProcessResult,this);
	//MessageBoxA(nullptr,GetQueueContent().c_str(),"receive",MB_OK);
}
std::string ChatClient::GetQueueContent()
{
	std::string ss="";

	std::for_each(m_deque.begin(),m_deque.end(),[&ss,this](std::string it)
	{
		this->m_deque;
		ss=ss+it;
	});
	return ss;
}
BOOL ChatClient::Login(const char *user,const char *uid,int scene_id,int league_id,int lock,const char* type)
{
	char md5_str[128]={0};
	strcpy_s(md5_str,key);
	strcat_s(md5_str,user);
	std::string str_src(md5_str);
	MD5 md5(str_src);
	std::string md5_dest=md5.hexdigest();
	char * pcommand=g_command[plogin];
	const char * login_str="{\"c\":\"%s\",\"key\":\"%s\",\"adminkey\":\"%s\",\"scene_id\":%d,\"league_id\":%d,\"lock\":%d,\"u\":\"%s\",\"t\":\"%s\"}";
	const char *admin_key="管理员密钥";
	wstring wx=ANSIToUnicode(admin_key);
	string ss=UnicodeToUTF8(wx);
	return ChatCommon(login_str,pcommand,md5_dest.c_str(),ss.c_str(),scene_id,league_id,lock,user,type);

}
BOOL ChatClient::ShutdownServer()
{
	char * pcommand=g_command[pshutdown];
	const char *shutdownstr="{\"c\":\"%s\"}";
	return ChatCommon(shutdownstr,pcommand);
}
BOOL ChatClient::GetAllMapUsers(const char*type)
{
	char * pcommand=g_command[pgetallmapusers];
	const char *get_users="{\"c\":\"%s\",\"type\":\"%s\"}";
	return ChatCommon(get_users,pcommand,type);
}

BOOL ChatClient::GetUserInfo(const char *user)
{
	char* pcommand=g_command[pgetuserinfo];
	const char* user_info="{\"c\":\"%s\",\"u\":\"%s\"}";
	return ChatCommon(user_info,pcommand,user);
}

BOOL  ChatClient::AddBlackList(char const *user)
{

	char *pcommand=g_command[paddblacklist];
	const char* add_black="{\"c\":\"%s\",\"u\":\"%s\"}";
	return ChatCommon(add_black,pcommand,user);
}

BOOL ChatClient::RemoveBlackList(const char* user)
{
	char *pcommand=g_command[premoveblacklist];
	const char* add_black="{\"c\":\"%s\",\"u\":\"%s\"}";
	return ChatCommon(add_black,pcommand,user);
}

BOOL ChatClient::KickUser(const char* user)
{
	char *pcommand=g_command[pkickuser];
	const char * kick="{\"c\":\"%s\",\"u\":\"%s\"}";
	return ChatCommon(kick,pcommand,user);
}
BOOL ChatClient::Heart()
{
    char * pcommand=g_command[pheart];
	const char *heart_str="{\"c\":\"%s\"}";
	return ChatCommon(heart_str,pcommand);
}

BOOL ChatClient::RejectIp(const char *ip)
{
	char * pcommand=g_command[preject];
	const char *heart_str="{\"c\":\"%s\",\"ip\":\"%s\"}";
	return ChatCommon(heart_str,pcommand,ip);
}

BOOL ChatClient::UnRejectIp(const char* ip)
{
	char * pcommand=g_command[punreject];
	const char *heart_str="{\"c\":\"%s\",\"ip\":\"%s\"}";
	return ChatCommon(heart_str,pcommand,ip);
}
BOOL ChatClient::SendToServer( const char * str,BOOL front)
{
	int len=strlen(str)+1;
	char *new_str=new char[len];
	memset(new_str,0,len);
	strcpy_s(new_str,len,str);
	Send(new_str,len);
	if(!front)
	{
		m_send_queue.push_back(new_str);
	}else{
		m_send_queue.push_front(new_str);
	}

	return TRUE;
}

BOOL ChatClient::ChatCommon(const char * format,...)
{
	va_list list;
	char pbuffer[BUFF_LEN]={0};
	memset(pbuffer,0,BUFF_LEN);
	va_start(list,format);
	vsprintf_s(pbuffer,BUFF_LEN,format,list);
	va_end(list);
	//wstring wx=ANSIToUnicode(pbuffer);
	//string ss=UnicodeToUTF8(wx);
	return SendToServer(pbuffer);
}
ChatClient::~ChatClient()
{
	delete s_client;
}


// ChatClient member functions
